package com.xiaoye.qbproject.handle;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xiaoye.qbproject.domain.ZbAttr;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedTypes;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

@Component
@MappedTypes(List.class)
public class GenericListTypeHandler extends BaseTypeHandler<List<?>> {

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, List<?> parameter, JdbcType jdbcType) throws SQLException {
        try {
            String json = objectMapper.writeValueAsString(parameter);
            ps.setString(i, json);
        } catch (JsonProcessingException e) {
            throw new SQLException("Error converting list to JSON", e);
        }
    }

    @Override
    public List<?> getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return parseJson(rs.getString(columnName), rs, columnName);
    }

    @Override
    public List<?> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return parseJson(rs.getString(columnIndex), rs, columnIndex);
    }

    @Override
    public List<?> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return parseJson(cs.getString(columnIndex), cs, columnIndex);
    }

    private List<?> parseJson(String json, Object source, Object identifier) throws SQLException {
        if (json == null) {
            return null;
        }
        try {
            // 获取目标Java类型，假设存在获取泛型信息的方法
            JavaType javaType = extractJavaType(source, identifier);
            JavaType elementType = javaType.getContentType();
            return objectMapper.readValue(json,
                    objectMapper.getTypeFactory().constructCollectionType(List.class, elementType.getRawClass()));
        } catch (IOException e) {
            throw new SQLException("Error parsing JSON to list", e);
        }
    }

      private JavaType extractJavaType(Object source, Object identifier) {
        // 尝试从ResultSet中获取列类型信息
        if (source instanceof ResultSet) {
            ResultSet rs = (ResultSet) source;
            try {
                String columnName = identifier instanceof String ? (String) identifier : rs.getMetaData().getColumnName((Integer) identifier);
                String columnClassName = rs.getMetaData().getColumnClassName(rs.findColumn(columnName));

                // 如果是List<ZbAttr>类型
                if (columnClassName != null && columnClassName.contains("ZbAttr")) {
                    return objectMapper.getTypeFactory().constructParametricType(List.class, ZbAttr.class);
                }
            } catch (SQLException e) {
                // 忽略异常，使用默认类型
            }
        }
        // 默认返回List<Object>类型
        return objectMapper.getTypeFactory().constructParametricType(List.class, Object.class);
    }
}